package compressor

import (
	ds "gitee.com/shipnet/flogo_edge_channel_data_store"
	"github.com/project-flogo/core/data/coerce"
)

type Settings struct {
}

type Input struct {
	Encoder          string                 `md:"encoder" json:"encoder,omitempty"`
	EncoderParams    map[string]interface{} `md:"encoderParams" json:"encoderParams,omitempty"`
	Compressor       string                 `md:"compressor" json:"compressor,omitempty"`
	CompressorParams map[string]interface{} `md:"compressorParams" json:"compressorParams,omitempty"`
	Data             []ds.EdgeChannelData   `md:"data" json:"data,omitempty"`
}

func (r *Input) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"encoder":          r.Encoder,
		"encoderParams":    r.EncoderParams,
		"compressor":       r.Compressor,
		"compressorParams": r.CompressorParams,
		"data":             toArray(r.Data),
	}
}

func toArray(data []ds.EdgeChannelData) []map[string]interface{} {
	arr := make([]map[string]interface{}, len(data))
	for index, d := range data {
		arr[index] = d.ToMap()
	}
	return arr
}

func (r *Input) FromMap(values map[string]interface{}) error {
	encoder, err := coerce.ToString(values["encoder"])
	if err != nil {
		return err
	}
	r.Encoder = encoder

	encoderParams, err := coerce.ToObject(values["encoderParams"])
	if err != nil {
		return err
	}
	r.EncoderParams = encoderParams

	compressor, err := coerce.ToString(values["compressor"])
	if err != nil {
		return err
	}
	r.Compressor = compressor

	compressorParams, err := coerce.ToObject(values["compressorParams"])
	if err != nil {
		return err
	}
	r.CompressorParams = compressorParams

	data, err := coerce.ToArray(values["data"])
	if err != nil {
		return err
	}
	eds := make([]ds.EdgeChannelData, len(data))
	for index, d := range data {
		dv, err := coerce.ToObject(d)
		if err != nil {
			return err
		}
		ed, err := ds.EdgeChannelDataFromMap(dv)
		if err != nil {
			return err
		}
		eds[index] = ed
	}
	r.Data = eds

	return nil
}

type CompressResult struct {
	Encoder          string                 `md:"encoder" json:"encoder,omitempty"`
	EncoderParams    map[string]interface{} `md:"encoderParams" json:"encoderParams,omitempty"`
	Compressor       string                 `md:"compressor" json:"compressor,omitempty"`
	CompressorParams map[string]interface{} `md:"compressorParams" json:"compressorParams,omitempty"`
	Data             []byte                 `md:"data" json:"data,omitempty"`
	Err              string                 `md:"err" json:"err,omitempty"`
}

func (r *CompressResult) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"encoder":          r.Encoder,
		"encoderParams":    r.EncoderParams,
		"compressor":       r.Compressor,
		"compressorParams": r.CompressorParams,
		"data":             r.Data,
		"err":              r.Err,
	}
}

func (r *CompressResult) FromMap(values map[string]interface{}) error {
	encoder, err := coerce.ToString(values["encoder"])
	if err != nil {
		return err
	}
	r.Encoder = encoder

	encoderParams, err := coerce.ToObject(values["encoderParams"])
	if err != nil {
		return err
	}
	r.EncoderParams = encoderParams

	compressor, err := coerce.ToString(values["compressor"])
	if err != nil {
		return err
	}
	r.Compressor = compressor

	compressorParams, err := coerce.ToObject(values["compressorParams"])
	if err != nil {
		return err
	}
	r.CompressorParams = compressorParams

	data, err := coerce.ToBytes(values["data"])
	if err != nil {
		return err
	}
	r.Data = data

	errStr, err := coerce.ToString(values["err"])
	if err != nil {
		return err
	}
	r.Err = errStr

	return nil
}

type Output struct {
	Result CompressResult `md:"result" json:"result,omitempty"`
}

func (r *Output) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"result": r.Result.ToMap(),
	}
}

func (r *Output) FromMap(values map[string]interface{}) error {
	resultMap, err := coerce.ToObject(values["result"])
	if err != nil {
		return err
	}
	var result CompressResult
	err = result.FromMap(resultMap)
	if err != nil {
		return err
	}
	r.Result = result

	return nil
}
